package copyengine.ui.component.list.old
{
	import copyengine.ui.component.CEUISprite;
	import copyengine.ui.component.button.CEButton;
	import copyengine.ui.component.list.old.animation.ICEListAnimation;
	import copyengine.ui.component.list.old.cellrender.ICECellRenderData;
	import copyengine.ui.component.list.old.dataprovider.ICEListDataProvider;
	import copyengine.ui.component.scrollbar.CEScrollBarCore;
	import copyengine.ui.component.scrollbar.CEScrollBarCoreEvent;
	import copyengine.utils.GeneralUtils;

	import flash.display.DisplayObjectContainer;
	import flash.events.MouseEvent;

	/**
	 * CEList is an list component, it include
	 * 				1) 6 buttons(nextOneBtn,prevOneBtn,nextPageBtn,prevPageBtn,firstOneBtn,lastOneBtn)
	 * 				2) 1 scrollBar
	 *
	 * user can init all or some of the component.
	 *
	 * for now CEList is not provide any events [TBD: maybe change later]
	 *
	 * @author Tunied
	 *
	 */
	public class CEList extends CEUISprite
	{

		/**
		 * turn to next one/page element
		 */
		private var nextOneBtn:CEButton;
		private var nextPageBtn:CEButton;

		/**
		 *turn to prev one/page element.
		 */
		private var prevOneBtn:CEButton;
		private var prevPageBtn:CEButton;

		private var startBtn:CEButton;
		private var endBtn:CEButton;

		/**
		 * List
		 */
		private var ceListCore:CEListCore;

		/**
		 * ScrollBar
		 */
		private var ceScrollBarCore:CEScrollBarCore;


		public function CEList(_target:DisplayObjectContainer, _ceListCore:CEListCore, _ceScrollBarCore:CEScrollBarCore, _nextOneBtn:CEButton = null,
							   _nextPageBtn:CEButton = null, _prevOneBtn:CEButton = null, _prevPageBtn:CEButton = null,
							   _startBtn:CEButton = null, _endBtn:CEButton = null)
		{
			super(_target);

			nextOneBtn = _nextOneBtn;
			nextPageBtn = _nextPageBtn;

			prevOneBtn = _prevOneBtn;
			prevPageBtn = _prevPageBtn;

			startBtn = _startBtn;
			endBtn = _endBtn;

			ceScrollBarCore = _ceScrollBarCore;
			ceListCore = _ceListCore;

			initialize();
		}

		protected function initialize():void
		{
			GeneralUtils.addTargetToParent(ceListCore, this);
			addListener();
		}

		override protected function doDispose():void
		{
			removeListener();

			GeneralUtils.removeTargetFromParent(nextOneBtn);
			GeneralUtils.removeTargetFromParent(nextPageBtn);
			GeneralUtils.removeTargetFromParent(prevOneBtn);
			GeneralUtils.removeTargetFromParent(prevPageBtn);
			GeneralUtils.removeTargetFromParent(startBtn);
			GeneralUtils.removeTargetFromParent(endBtn);
			GeneralUtils.removeTargetFromParent(ceListCore);
			GeneralUtils.removeTargetFromParent(ceScrollBarCore);
		}

		/**
		 * WARNINIG::
		 * 		you can set the dataProvider at CEList initialze, or you can set dataProvider by call function
		 * refreshDataProvider().
		 *
		 * =========
		 * ！！！！！！
		 * =========
		 *
		 * _listSelectableProperty应该默认值为SELECTABLE_CAN_NOT_SELECTED,但是直接使用const值编译不过去
		 *
		 * _listSelectableProperty = CEListConfig.SELECTABLE_CAN_NOT_SELECTED
		 */
		public function initializeCEList(_cellRenderInstanceClass:Class,
										 _dataProvider:ICEListDataProvider = null,
										 _listInteraction:ICEListAnimation = null,
										 _cellRenderAnimationClass:Class = null,
										 _listSelectableProperty:int = 1):void
		{
			ceListCore.initializeCEListCore(_cellRenderInstanceClass, _dataProvider, _listInteraction,
											_cellRenderAnimationClass, _listSelectableProperty);
			if (ceScrollBarCore != null)
			{
				ceScrollBarCore.initializeScrollBar(ceListCore.getLineScrollSize(), ceListCore.getPageScrollSize(),
													ceListCore.getMinScrollValue(), ceListCore.getMaxScrollValue());
			}
			refreshBtnState();
		}

		/**
		 * @see ceListCore.refreshDataProvider()
		 */
		public function refreshDataProvider(_dataProvider:ICEListDataProvider = null, _isCleanScrollPosition:Boolean = false):void
		{
			ceListCore.refreshDataProvider(_dataProvider, _isCleanScrollPosition);
			if (ceScrollBarCore != null)
			{
				ceScrollBarCore.refreshScrollBar(ceListCore.getLineScrollSize(), ceListCore.getPageScrollSize(),
												 ceListCore.getMinScrollValue(), ceListCore.getMaxScrollValue(), ceListCore.scrollPosition);
			}
			if (_isCleanScrollPosition)
			{
				if (ceScrollBarCore != null)
				{
					ceScrollBarCore.scrollPosition = 0;
				}
			}
			else
			{
				//in case when dataProvider change the old scrollPosition bigger than maxScrollPosition
				ceListCore.scrollPosition = GeneralUtils.normalizingValue(ceListCore.scrollPosition,
																		  ceListCore.getMinScrollValue(),
																		  ceListCore.getMaxScrollValue());
				if (ceScrollBarCore != null)
				{
					ceScrollBarCore.scrollPosition = ceListCore.scrollPosition;
				}
			}
			refreshBtnState();
		}

		public function getSelectedItems():Vector.<ICECellRenderData>
		{
			return ceListCore.getSelectableItems();
		}

		public function getListCellRenderCount():int
		{
			return ceListCore.getListCellRenderCount();
		}

		public function getListPageCount():int
		{
			return ceListCore.getListPageCount();
		}

		public function scrollToIndex(_groupIndex:int, _isPlayingAnimation:Boolean = true):void
		{
			ceListCore.scrollToIndex(_groupIndex, _isPlayingAnimation);
			refreshBtnState();
		}

		public function scrollToNextOne():void
		{
			ceListCore.scrollNext();
			refreshBtnState();
		}

		public function scrollToNextPage():void
		{
			ceListCore.scrollNextPage();
			refreshBtnState();
		}

		public function scrollToPrevOne():void
		{
			ceListCore.scrollPrev();
			refreshBtnState();
		}

		public function scrollToPrevPage():void
		{
			ceListCore.scrollPrevPage();
			refreshBtnState();
		}

		public function scrollToStart():void
		{
			ceListCore.scrollStart();
			refreshBtnState();
		}

		public function scrollToEnd():void
		{
			ceListCore.scrollEnd();
			refreshBtnState();
		}

		private function addListener():void
		{
			GeneralUtils.addTargetEventListener(nextOneBtn, MouseEvent.CLICK, onNextOneBtnClick);
			GeneralUtils.addTargetEventListener(nextPageBtn, MouseEvent.CLICK, onNextPageBtnClick);
			GeneralUtils.addTargetEventListener(prevOneBtn, MouseEvent.CLICK, onPrevOneBtnClick);
			GeneralUtils.addTargetEventListener(prevPageBtn, MouseEvent.CLICK, onPrevPageBtnClick);
			GeneralUtils.addTargetEventListener(startBtn, MouseEvent.CLICK, onStartBtnClick);
			GeneralUtils.addTargetEventListener(endBtn, MouseEvent.CLICK, onEndBtnClick);
			GeneralUtils.addTargetEventListener(ceListCore, CEListCoreEvent.SCROLL_START, ceListCoreOnScroll);
			GeneralUtils.addTargetEventListener(ceScrollBarCore, CEScrollBarCoreEvent.SCROLL, ceScrollBarCoreOnScroll);
			GeneralUtils.addTargetEventListener(ceListCore, MouseEvent.MOUSE_WHEEL, ceListOnMouseWheel);
		}

		private function removeListener():void
		{
			GeneralUtils.removeTargetEventListener(nextOneBtn, MouseEvent.CLICK, onNextOneBtnClick);
			GeneralUtils.removeTargetEventListener(nextPageBtn, MouseEvent.CLICK, onNextPageBtnClick);
			GeneralUtils.removeTargetEventListener(prevOneBtn, MouseEvent.CLICK, onPrevOneBtnClick);
			GeneralUtils.removeTargetEventListener(prevPageBtn, MouseEvent.CLICK, onPrevPageBtnClick);
			GeneralUtils.removeTargetEventListener(startBtn, MouseEvent.CLICK, onStartBtnClick);
			GeneralUtils.removeTargetEventListener(endBtn, MouseEvent.CLICK, onEndBtnClick);
			GeneralUtils.removeTargetEventListener(ceListCore, CEListCoreEvent.SCROLL_START, ceListCoreOnScroll);
			GeneralUtils.removeTargetEventListener(ceScrollBarCore, CEScrollBarCoreEvent.SCROLL, ceScrollBarCoreOnScroll);
			GeneralUtils.removeTargetEventListener(ceListCore, MouseEvent.MOUSE_WHEEL, ceListOnMouseWheel);
		}

		private function refreshBtnState():void
		{
			var isEnableNextBtn:Boolean = ceListCore.scrollPosition == ceListCore.getMaxScrollValue() ? false : true;
			var isEnablePrevBtn:Boolean = ceListCore.scrollPosition == ceListCore.getMinScrollValue() ? false : true;

			GeneralUtils.changeTargetEnableProperty(isEnableNextBtn, nextOneBtn);
			GeneralUtils.changeTargetEnableProperty(isEnableNextBtn, nextPageBtn);
			GeneralUtils.changeTargetEnableProperty(isEnableNextBtn, endBtn);
			GeneralUtils.changeTargetEnableProperty(isEnablePrevBtn, prevOneBtn);
			GeneralUtils.changeTargetEnableProperty(isEnablePrevBtn, prevPageBtn);
			GeneralUtils.changeTargetEnableProperty(isEnablePrevBtn, startBtn);
		}

		//================
		//== Event Listener
		//================

		//注意:: 
		//1·目前CEList组件存在Bug:
		//	如果上层调用监听CElistEvent.CLICK_NEXT_ONE_BTN等Event,并且在收到请求后调用
		//	refreshDataProvider() 和 scrollToIndex()设置CellRender显示的Index则会出现CellRender立即跳到相应的Cellrender不播放Animation
		//	原因不明,可能由于两个函数导致了Animation.kill
		// 2·对于CElistEvent.CLICK_NEXT_ONE_BTN 每次点击不代表Cellrender真向后翻了一个,因为在翻滚中玩家继续点击按钮
		//	此时会dispatchEvent，但是其实CellRender的并没有继续向后翻,比如刚才Index是1,点击向后翻按钮一次上层函数记录Index为2
		// 但是动画没有播完,此时又点击了一次按钮，上次函数记录Index为3,但是CellRender中Index仍旧为2
		//
		//  目前的解决方法是,如果上层监听Event,则本类中不在操作List操作,又外层调用scrollToIndex()操作List组件
		//

		private function onNextOneBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_NEXT_ONE_BTN);
			!result && scrollToNextOne();
		}

		private function onNextPageBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_NEXT_PAGE_BTN);
			!result && scrollToNextPage();
		}

		private function onPrevOneBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_PREV_ONE_BTN);
			!result && scrollToPrevOne();
		}

		private function onPrevPageBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_PREV_PAGE_BTN);
			!result && scrollToPrevPage();
		}

		private function onStartBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_STATRT_BTN);
			!result && scrollToStart();
		}

		private function onEndBtnClick(e:MouseEvent):void
		{
			var result:Boolean = tryToDispathEvent(CElistEvent.CLICK_END_BTN);
			!result && scrollToEnd();
		}


		private function ceListCoreOnScroll(e:CEListCoreEvent):void
		{
			if (ceScrollBarCore != null)
			{
				ceScrollBarCore.scrollPosition = e.expectScrollPositon;
			}
		}

		private function ceListOnMouseWheel(e:MouseEvent):void
		{
			ceScrollBarCore && e.delta < 0 ? scrollToNextOne() : scrollToPrevOne();
		}

		private function ceScrollBarCoreOnScroll(e:CEScrollBarCoreEvent):void
		{
			ceListCore.scrollPosition = e.scrollPosition;
			refreshBtnState();
		}

		private function tryToDispathEvent(_type:String):Boolean
		{
			if (this.hasEventListener(_type))
			{
				var e:CElistEvent = new CElistEvent(_type);
				this.dispatchEvent(e);
				return true;
			}
			return false;
		}

	}
}
